package com.zzuli.yxy.task;

import com.alibaba.fastjson.JSON;
import com.zzuli.yxy.entity.Song;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.zzuli.yxy.service.SongService;
import com.zzuli.yxy.task.springDataPipeline.SongLyricPipeline;
import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.Request;
import us.codecraft.webmagic.Site;
import us.codecraft.webmagic.Spider;
import us.codecraft.webmagic.processor.PageProcessor;
import us.codecraft.webmagic.scheduler.BloomFilterDuplicateRemover;
import us.codecraft.webmagic.scheduler.QueueScheduler;
import us.codecraft.webmagic.selector.Json;

import java.util.List;
import java.util.Map;

/**
 * 目标地址：http://music.163.com/api/song/lyric?id= + songId + &lv=1&kv=1&tv=-1
 * 获取热歌榜歌曲
 * 获取网易云歌词
 * @auther pony
 * @create 2023-04-04 15:07
 */
@Component
public class SongLyricTask implements PageProcessor {

    // 歌曲带时间的歌单信息
    private static String songIrcPre = "http://music.163.com/api/song/lyric?id=";
    private static String songIrcSuf = "&lv=1&kv=1&tv=-1";

    @Autowired
    private SongService songService;
    @Override
    public void process(Page page) {
        Json json = page.getJson();
        if (json!=null){
            Song song = new Song();
            //1、获取 url，获得 歌曲id
            String url = page.getUrl().toString();
            System.out.println("歌曲url:"+url);
            Integer songId = Integer.valueOf(url.substring(url.lastIndexOf("id=")+3, url.lastIndexOf("&lv")));
            System.out.println("歌曲id:"+songId);
            song.setSongId(songId);
            //System.out.println(songId);
            //String lyricString = JSON.toJSONString(json);
            //System.out.println(lyricString);
            //2、解析 json 获取歌曲信息
            // 先将json 转 map，获取 lrc 里面的数据
            Map map = JSON.parseObject(json.toString());
            Object lrc = map.get("lrc");
            //System.out.println("lrc："+lrc);
            // 将 lrc 对象再转 Json 字符串
            String lrcJson = JSON.toJSONString(lrc);
            // System.out.println("lyric："+lrcJson );
            // 然后再将 lrcJson 再转 map
            Map map1 = JSON.parseObject(lrcJson);
            // 获取歌词 lyric 对象
            Object lyric = map1.get("lyric");
            // 将 lyric 对象 转 json ，带 "。。。。"
            String lyricString = JSON.toJSONString(lyric);
            // 通过截取去掉 歌词前后 ""
            String songLyric = lyricString.substring(lyricString.indexOf("\"") + 1, lyricString.lastIndexOf("\""));
            System.out.println("*********************************************************************************************************************************************");
            System.out.println("歌词："+ songLyric);
            song.setSongLyric(songLyric);

            page.putField("songLyric", song);
        }
    }

    private Site site = Site.me();
    @Override
    public Site getSite(){
        return site;
    }
    @Autowired
    private SongLyricPipeline songLyricPipeline;
    // 获取热歌榜所有歌曲的 id
    // 每周一 凌晨1 点，执行一遍更新数据
    //@Scheduled(cron = "0 0 1 ? * 1")
//    @Scheduled(initialDelay = 10 * 1000, fixedRate=1000*60*60*24*7)
    public void process() {
        //1、查询数据库，获取所有歌曲
        List<Song> songlist = songService.list();
        //2、遍历 songList，得到每首歌的 id
        for (Song song : songlist) {
            // 3、通过id，拼接要爬虫地址
            Integer songId = song.getSongId();
            String url = songIrcPre + songId + songIrcSuf;
            // 4、配置请求信息
            Request request = new Request(url);
            // 请求方法
            request.setMethod("GET");
            // 浏览器基本信息，用于反爬
            request.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36");

            Spider.create(new SongLyricTask())
                    .addRequest(request)
                    // 使用布隆过滤器进行去重， 10000 大概要放的数据，数据越大越慢
                    // 使用前先引一个新版本的依赖
                    .setScheduler(new QueueScheduler().setDuplicateRemover(new BloomFilterDuplicateRemover(10000)))
                    .thread(10)
                    .addPipeline(this.songLyricPipeline)
                    .run();
        }
    }
}
